﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace OBDUDSUtils.CNNMode
{
    public enum CANType
    {
        /// <summary>
        /// 周立功CAN
        /// </summary>
        ZLGCAN,

        /// <summary>
        /// Peak CAN
        /// </summary>
        PeakCAN,

        /// <summary>
        /// Etas CAN
        /// </summary>
        Etas581,

        /// <summary>
        /// Mongoonse
        /// </summary>
        MongooseProISO,

        /// <summary>
        /// kwykawayi
        /// </summary>
        K_CAN
    }

    public enum RunMode
    {
        /// <summary>
        /// 查询MODE
        /// </summary>
        SidMode,

        /// <summary>
        /// 手动测试
        /// </summary>
        ManualTest,

        /// <summary>
        /// UDS服务
        /// </summary>
        UDS,

        UDS_MESE6,
        UDS_MESE8,
        UDS_UP6,
        UDS_MT05
    }

    public enum PVEQueryMode
    {
        OBDIIMode,
        AutoMode,
        FuncMode
    }

    public enum DIDRequestStatus
    {
        NoneData,
        Successful,
        Fail
    }

    /// <summary>
    /// Represents the type of PCAN (Non-PnP) hardware to be initialized
    /// </summary>
    public enum TPCANType : byte
    {
        /// <summary>
        /// PCAN-ISA 82C200
        /// </summary>
        PCAN_TYPE_ISA = 0x01,
        /// <summary>
        /// PCAN-ISA SJA1000
        /// </summary>
        PCAN_TYPE_ISA_SJA = 0x09,
        /// <summary>
        /// PHYTEC ISA 
        /// </summary>
        PCAN_TYPE_ISA_PHYTEC = 0x04,
        /// <summary>
        /// PCAN-Dongle 82C200
        /// </summary>
        PCAN_TYPE_DNG = 0x02,
        /// <summary>
        /// PCAN-Dongle EPP 82C200
        /// </summary>
        PCAN_TYPE_DNG_EPP = 0x03,
        /// <summary>
        /// PCAN-Dongle SJA1000
        /// </summary>
        PCAN_TYPE_DNG_SJA = 0x05,
        /// <summary>
        /// PCAN-Dongle EPP SJA1000
        /// </summary>
        PCAN_TYPE_DNG_SJA_EPP = 0x06,
    }

    /// <summary>
    /// Represents a PCAN Baud rate register value
    /// </summary>
    public enum TPCANBaudrate : ushort
    {
        /// <summary>
        /// 1 MBit/s
        /// </summary>
        PCAN_BAUD_1M = 0x0014,
        /// <summary>
        /// 800 KBit/s
        /// </summary>
        PCAN_BAUD_800K = 0x0016,
        /// <summary>
        /// 500 kBit/s
        /// </summary>
        PCAN_BAUD_500K = 0x001C,
        /// <summary>
        /// 250 kBit/s
        /// </summary>
        PCAN_BAUD_250K = 0x011C,
        /// <summary>
        /// 125 kBit/s
        /// </summary>
        PCAN_BAUD_125K = 0x031C,
        /// <summary>
        /// 100 kBit/s
        /// </summary>
        PCAN_BAUD_100K = 0x432F,
        /// <summary>
        /// 95,238 KBit/s
        /// </summary>
        PCAN_BAUD_95K = 0xC34E,
        /// <summary>
        /// 83,333 KBit/s
        /// </summary>
        PCAN_BAUD_83K = 0x852B,
        /// <summary>
        /// 50 kBit/s
        /// </summary>
        PCAN_BAUD_50K = 0x472F,
        /// <summary>
        /// 47,619 KBit/s
        /// </summary>
        PCAN_BAUD_47K = 0x1414,
        /// <summary>
        /// 33,333 KBit/s
        /// </summary>
        PCAN_BAUD_33K = 0x8B2F,
        /// <summary>
        /// 20 kBit/s
        /// </summary>
        PCAN_BAUD_20K = 0x532F,
        /// <summary>
        /// 10 kBit/s
        /// </summary>
        PCAN_BAUD_10K = 0x672F,
        /// <summary>
        /// 5 kBit/s
        /// </summary>
        PCAN_BAUD_5K = 0x7F7F,
    }

    public class DiagData
    {
        #region 公有参数
        /// <summary>
        /// 保存单一MODE数据
        /// </summary>
        //public List<string> ModeResultData;

        public RunMode OperateMode { get; set; } = RunMode.SidMode;

        public PVEQueryMode PVEQRunMode { get; set; }

        /// <summary>
        /// 是否开启通道
        /// </summary>
        public bool IsStartChannel { get; set; } = false;

        /// <summary>
        /// 自动模式-启动SID7服务循环
        /// </summary>
        public bool IsStartSID7Service { get; set; }

        /// <summary>
        /// true-等待-未完成，false-已完成
        /// </summary>
        public bool AutoModeWaitState { get; set; }

        /// <summary>
        /// 自动模式-启动SID1服务循环
        /// </summary>
        public bool IsStartSID1Service { get; set; }

        public int SSid { get; set; }

        public int SPID { get; set; }

        public uint SFrameID { get; set; }

        public byte[] SData { get; set; }

        /// <summary>
        /// SID查询时的第一个字节
        /// </summary>
        public byte SFirstByte { get; set; }

        /// <summary>
        /// 保存mode6数据
        /// </summary>
        public System.Data.DataTable Mode6Data;

        /// <summary>
        /// List view当前选择行索引
        /// </summary>
        public int SelectOBDListIndex { get; set; } = -1;

        /// <summary>
        /// 诊断查询模式，单个查询或一键查询
        /// </summary>
        public bool IsStartOneKeyQueryOfSid { get; set; } = false;

        /// <summary>
        /// 启动一键查询时，保存的所有SID数据
        /// </summary>
        public StringBuilder AllSaveSidData { get; set; }

        /// <summary>
        /// INI配置文件的绝对路径
        /// </summary>
        public string ConfigFileName { get; set; }

        /// <summary>
        /// 是否保存报文
        /// </summary>
        public bool IsSaveMessage { get; set; }

        /// <summary>
        /// 0-周立功CAN，1-PCAN
        /// </summary>
        public CANType CANType { get; set; }

        public DiagBasic.ModelSID ModeType { get; set; }

        /// <summary>
        /// 为当前CAN的最终连接状态
        /// </summary>
        public bool CANConnectStatus { get; set; }

        /// <summary>
        /// 当前单帧/多帧数据接收并解析完成标志
        /// </summary>
        public bool AnalysisCompleted { get; set; }

        /// <summary>
        /// 请求PID的地址，初始值为0，依次增加0x20
        /// </summary>
        public int FramePIDNextID { get; set; } = 0;

        /// <summary>
        /// 接收所有PID完成
        /// </summary>
        public bool IsAllPIDRevCompleted { get; set; } = false;

        /// <summary>
        /// 请求查询SID服务时，启动超时等待，true-已启动，开始等待查询完成，false-未启动或已完成/已结束
        /// </summary>
        public bool IsStartModeWait { get; set; } = false;

        public TimeSpan StartTimeSpan { get; set; }

        public TimeSpan StartPidTimeSpan { get; set; }

        public bool IsStartPidWait { get; set; } = false;

        public bool WaitPCANModeCompleted = false;

        /// <summary>
        /// 解析所有PID内容完成
        /// </summary>
        public bool IsReadSupplyPIDComplete { get; set; } = false;

        /// <summary>
        /// 存储支持的PID集合
        /// </summary>
        public List<byte> PidOfSupplyList { get; set; }

        /// <summary>
        /// 存储支持的PID队列，取出解析时用
        /// </summary>
        public Queue<byte> PidOfSupplyQueue { get; set; }

        /// <summary>
        /// 控制指令发送
        /// </summary>
        public bool IsStopSendFlag { get; set; } = false;

        /// <summary>
        /// 查询支持的PID时有效数据的起始索引
        /// </summary>
        public int CalSupplyPIDStartIndex { get; set; } = 0;

        /// <summary>
        /// 存储接收到的代码HEX，PID + 数据
        /// </summary>
        public List<string> CodesResult { get; set; }

        /// <summary>
        /// 接收的代码数量
        /// </summary>
        public int DataCodeNumber { get; set; } = 0;

        /// <summary>
        /// 解析到当前UDS DID是否完成
        /// </summary>
        public bool DIDAnalysisCompleted { get; set; }

        #endregion

        /// <summary>
        /// 查询的SID数据，用于保存时使用
        /// </summary>
        public List<DiagEntity> DiagSidData { get; set; }

        /// <summary>
        /// 文件存储相关配置
        /// </summary>
        public ConfigEntity ConfigEntity { get; set; }

        /// <summary>
        /// MongooseISO相关配置
        /// </summary>
        public MongooseConfig MongooseDevice { get; set; }

        public ZLGCANConfig ZLGCANDevice { get; set; }

        public PeakCANConfig PeakCANDevice { get; set; }

        public EtasCANConfig EtasDevice { get; set; }

        public MessageBasic MessageBasicCfg { get; set; }

        //public OBDUDSUtils.ZlgControl.CANDevice _ZlgDiag { get; set; }
        //public OBDUDSUtils.PCAN_OBD.PBasicDiag _PBasicDiag { get; set; }
        //public OBDUDSUtils.EtasCAN.Es581_OBDMode _ES581Diag { get; set; }
        //public OBDUDSUtils.Mongoose.MongooseDiag _MongooseDiag { get; set; }
    }

    public class ZLGCANConfig
    {
        public uint FrameID { get; set; } = 0x7df;
        public int Sid { get; set; }
        public int Pid { get; set; }
        public int Mid { get; set; }
        public byte[] Data { get; set; } = new byte[8];

        public List<int> CANFilterID { get; set; } = new List<int>() { 0x7e8 };

        /// <summary>
        /// 设备类型号
        /// </summary>
        public UInt32 DeviceType { get; set; } = 21;//usbcan2e

        /// <summary>
        /// 设备索引
        /// </summary>
        public UInt32 DeviceID { get; set; } = 0;

        /// <summary>
        /// 波特率寄存器地址
        /// </summary>
        public UInt32 BaudRateAdress { get; set; }

        /// <summary>
        /// 设备CAN通道ID CAN0=1，CAN1=0
        /// 默认OBDII/UDS优先使用通道
        /// </summary>
        public UInt32 DeviceCANID { get; set; } = 1;
    }

    public class MongooseConfig
    {
        public const uint FLOW_CONTROL_FILTER = 0x00000003;
        public const uint ISO15765_FRAME_PAD = 0x00000040;
        public const uint CLEAR_RX_BUFFER = 0x08;
        public const uint CLEAR_TX_BUFFER = 0x07;

        public IntPtr DeviceName { get; set; }

        /// <summary>
        /// 打开设备时获取
        /// </summary>
        public uint DeviceID { get; set; }

        /// <summary>
        /// 连接设备时获取
        /// </summary>
        public uint ChannelID { get; set; }

        /// <summary>
        /// 由外部配置
        /// </summary>
        public uint ProtocolID { get; set; } = 6;

        public uint FrameID { get; set; } = 0x7df;

        public int Sid { get; set; }
        public int Pid { get; set; }
        public int Mid { get; set; }
        public byte[] Data { get; set; } = new byte[8];

        public uint Flags { get; set; } = 0;

        public uint BaudRate { get; set; }

        public uint MsgID { get; set; } = 1;

        /// <summary>
        /// Mongoose连接状态
        /// </summary>
        public bool MongooseConnected { get; set; }
    }

    public class PeakCANConfig
    {
        public UInt16 PeakCANChannel { get; set; } = 0x51;

        public TPCANBaudrate BaudRate { get; set; }
   
        /// <summary>
        /// Arbitration: 1 Mbit/sec
        /// Data: 2 Mbit/sec
        /// </summary>
        public string BaudRateFD = "f_clock_mhz=20, nom_brp=5, nom_tseg1=2, nom_tseg2=1, nom_sjw=1, data_brp=2, data_tseg1=3, data_tseg2=1, data_sjw=1";

        public uint FrameID { get; set; } = 0x7df;

        public int Sid { get; set; }
        public int Pid { get; set; }
        public int Mid { get; set; }
        public byte[] Data { get; set; } = new byte[8];

        public bool IsExtendedFrame { get; set; } = false;

        public bool IsRemoteFrame { get; set; } = false;

        public bool IsCheckedCANFD { get; set; } = false;

        /// <summary>
        /// 比特率开关
        /// </summary>
        public bool IsBitRateSwitch { get; set; } = false;

        public TPCANType PCANHWType { get; set; } = 0;

        public uint IOPort { get; set; } = 0x100;

        public ushort Interrupt { get; set; } = 3;

        public bool IsStartFilter { get; set; } = true;

        public uint FilterMin { get; set; } = 0x7df;

        public uint FilterMax { get; set; } = 0x7e8;
    }

    public class EtasCANConfig
    {
        public int OpenDeviceType { get; set; }

        public IntPtr m_hObject;

        public string EsNetWork { get; set; }

        public uint FrameID { get; set; } = 0x7df;
        public int Sid { get; set; }
        public int Pid { get; set; }
        public int Mid { get; set; }
        public byte[] Data { get; set; } = new byte[8];

        public int EsNumberOfBytes { get; set; } = 8;

        public bool IsExtendedID { get; set; }
    }

    public class CANResult
    {
        public int FrameID { get; set; }

        public byte[] Data { get; set; }
    }

    public class ConfigEntity
    {
        public const string RootDataFile = "C:\\UniversalDiagnosticTool\\Data\\";
        public const string MessageDataFile = "messageData\\";
        public const string DataResultFile = "queryData\\";

        public bool IsAutoSave { get; set; } = false;

        /// <summary>
        /// 相对路径
        /// </summary>
        //public string LoggerFilePath { get; set; }

        /// <summary>
        /// 报文与数据保存的根目录,默认：c:\\UniversalDiagnosticTool\\Data\\
        /// </summary>
        public string DataRootPath { get; set; } = "C:\\UniversalDiagnosticTool\\Data\\";

        /// <summary>
        /// 报文路径=根目录 + messageData\\
        /// </summary>
        public string MessagePath { get; set; }

        /// <summary>
        /// 数据路径=根目录 + queryData
        /// </summary>
        public string DataResultPath { get; set; }

        public string CurrentDataResultPath { get; set; }

        public bool SelfChecked { get; set; }

        /// <summary>
        /// 相对路径
        /// </summary>
        public string LoggerFilePath { get; set; }

        public List<DatabaseHistoryPath> DbHisPathList { get; set; }
    }

    public class DatabaseHistoryPath
    {
        public int DbIndex { get; set; }

        public string DbKey { get; set; }

        public string Absolutepath { get; set; }
    }

    public class DiagEntity
    {
        public DiagBasic.ModelSID ModeType { get; set; }

        /// <summary>
        /// 按行显示的MODE结果
        /// </summary>
        //public string PIDResultLine { get; set; }

        /// <summary>
        /// 存储故障码
        /// </summary>
        //public List<string> FaultCodes { get; set; }
        public DataSid12 OBDDataSid12 { get; set; }

        public DataSid4 OBDDataSid4 { get; set; }

        public DataSid37A OBDDataSid37A { get; set; }

        public DataSid9 OBDDataSid9 { get; set; }
        
        public DataSid6 OBDDataSid6Data { get; set; }

        /// <summary>
        /// 用于周立功CAN模式下的DID存储
        /// </summary>
        //public Queue<DidResultEntity> UDSDidDataQueue { get; set; }

        public DidResultEntity DidResultData { get; set; }

        public List<DidResultEntity> PidResults { get; set; }
    }

    public class DataSid6
    {
        public string MonitorID { get; set; }

        public string TestID { get; set; }

        public string UnitID { get; set; }

        /// <summary>
        /// 精确到小数点后7位
        /// </summary>
        public string TestValue { get; set; }

        public string TestMinVaule { get; set; }

        public string TestMaxValue { get; set; }

        public string UnitStr { get; set; }

        public string Describle { get; set; }
    }

    public class DataSid12
    {
        public int PID { get; set; }

        public string PIDClumnStr { get; set; }

        public string TestItemValue { get; set; }

        public string TestItemUnit { get; set; }

        public string TestItemDescrible { get; set; }

        public string TestResult { get; set; }
    }

    public class DataSid37A
    {
        public string FaultCode { get; set; }

        public string Describle { get; set; }
    }

    public class DataSid4 
    {
        public string FaultCode { get; set; }

        public string ClearResult { get; set; }
    }

    public class DataSid9
    {
        public int PID { get; set; }

        public string PIDClumnStr { get; set; }

        public string TestItemValue { get; set; }

        public string TestItemUnit { get; set; }

        public string TestItemDescrible { get; set; }
    }

    public class DidResultEntity
    {
        /// <summary>
        /// 数据长度，1byte-len, 2-3byte-did
        /// </summary>
        public int DataLength { get; set; }

        public byte DidResponseID { get; set; } = 0x62;

        /// <summary>
        /// 请求的两字节DID
        /// </summary>
        public ushort UsedDId { get; set; }

        public DIDRequestStatus DidResultStatus { get; set; }

        public List<byte> DidResults { get; set; }
    }

    /// <summary>
    /// 收发模式下，基础配置
    /// </summary>
    public class MessageBasic
    {
        /// <summary>
        /// 默认显示帧行数
        /// </summary>
        public int FrameNumber { get; set; } = 1000;

        /// <summary>
        /// 用于计算的起始行索引
        /// </summary>
        public int StartRowIndex { get; set; } = 0;

        public int RowOrder { get; set; } = 0;
    }
}
